package com.fingard.dsp.bank.directbank.mufg01;

import java.io.File;
import java.util.Calendar;
import java.util.Date;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.bankInterface.IBalance;
import com.fingard.dsp.bank.reqrespobj.balance.Req7505HisBalQry;
import com.fingard.dsp.bank.reqrespobj.balance.Req7506BalQry;
import com.fingard.dsp.bank.reqrespobj.balance.RetAts7505HisBalQry;
import com.fingard.dsp.bank.reqrespobj.balance.RetAts7506BalQry;
import com.fingard.dsp.bank.reqrespobj.balance.detail.RetAtsBalDetail;
import com.fingard.dsp.bank.reqrespobj.balance.detail.RetAtsHisBalDetail;
import com.fingard.io.FileHelper;
import com.fingard.text.StringHelper;
import com.fingard.util.DateHelper;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

/**
 * 三菱银行
 * @version 1.0
 */
public class MUFG01Balance extends MUFG01Base implements IBalance {

    @Override
    public RetAts7506BalQry d_7506_BalQry(Req7506BalQry p_req7506) throws Exception {
        return "1".equals(getBankConfig().getValueAsString("channelFlag"))?d_7506_BalQry_Xml(p_req7506):d_7506_BalQry_MT(p_req7506);
    }

    /**
     * MT文件方式--今日余额查询
     * @param p_req7506
     * @return
     * @throws Exception
     */
    public RetAts7506BalQry d_7506_BalQry_MT(Req7506BalQry p_req7506) throws Exception {
        //创建返回对象
        RetAts7506BalQry retAts = new RetAts7506BalQry(p_req7506.reqHeader);
        //写返回ATS的统一头部信息
        retAts.writeStart();
        while(p_req7506.readRecord()){
            //创建返回到ATS余额对象
            RetAtsBalDetail detail = new RetAtsBalDetail();
            //获取账号
            String accNum = p_req7506.readedDetail.actNum;
            //设置时间
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date());
            String dealedFile = getBankConfig().getValueAsString("DealedPath")+ File.separator+
                    Format.Date8Format.format(calendar.getTime())+ File.separator+"MT942"+File.separator+accNum+"_7506.txt";
            //如果当天日间文件还没收到，就取前一天的日终文件，
            //如果前一天的日终文件没收到，说明是节假日，就继续往前遍历，最多10天
            int num =1;
            String day=getBankConfig().getValueAsString("countDay");//往前遍历天数
            while(!FileHelper.existFile(dealedFile)&&num<=Integer.parseInt(StringHelper.isNullOrEmpty(day) ?"10":day)){
                WriteBankLogLn("账户"+accNum+"在"+calendar+"日期的MT940文件不存在,继续往前一天遍历，第"+num+"次");
                calendar.add(Calendar.DAY_OF_MONTH,-1);
                dealedFile = getBankConfig().getValueAsString("DealedPath")+File.separator+
                        Format.Date8Format.format(calendar.getTime())+File.separator+
                        "MT940"+File.separator+accNum+"_7505.txt";
                num++;
            }
            if(!FileHelper.existFile(dealedFile)){
                detail.respCode ="0";
                detail.respInfo="此账号余额暂时无法获取";
            }
            //读取文件内容
            String balanceContent = FileHelper.readFileText(dealedFile,getCharset());
            WriteBankLogLn("读取到的文件内容："+balanceContent);
            if(StringHelper.hasAnyChar(balanceContent)){
                //账号|币种|当前余额|可用余额|昨日余额(MT940)|页码|
                //账号|币种|当前余额|可用余额|期初余额|(MT942)
                String[] bal  =balanceContent.split("\\|");
                detail.respCode ="0";
                detail.actNum =bal[0].trim();
                detail.actCur =convertCurToATS(bal[1].trim());
                detail.currBal =bal[2].trim();
                detail.availBal =bal[3].trim();
                detail.yesterdayBal = bal[4].trim();
            }else {
                detail.respCode="-1";
                detail.respInfo="文件读取异常";
            }
            retAts.writeRetDetail(detail,p_req7506.isBatch);
        }
        retAts.writeEnd();
        return retAts;
    }

    /**
     * 请求报文方式--今日余额查询
     * @param p_req7506
     * @return
     * @throws Exception
     */
    public RetAts7506BalQry d_7506_BalQry_Xml(Req7506BalQry p_req7506) throws Exception {
        //创建返回对象
        RetAts7506BalQry retAts = new RetAts7506BalQry(p_req7506.reqHeader);
        //写返回ATS的统一头部信息
        retAts.writeStart();
        while(p_req7506.readRecord()) {
            //创建返回到ATS余额对象
            RetAtsBalDetail detail = new RetAtsBalDetail();
            //拼接请求报文体
            MUFG01Header header=new MUFG01Header();
            header.transCode="h2h.001.001";
            header.pkgNo = getQryTransID();
            XmlTextWriter xmlReq = new XmlTextWriter();
            writeReqHeader(xmlReq,header);
            xmlReq.writeStartElement("req");
            xmlReq.writeElementString("accNo",p_req7506.readedDetail.actNum);//帐号
            xmlReq.writeElementString("beginDate",Format.Date10Format.format(new Date()));//查询开始日期
            xmlReq.writeElementString("endDate",Format.Date10Format.format(new Date()));//查询结束日期
            xmlReq.writeEndDocument();
            //请求银行并获取响应结果
            String[] bankResult = sendToBank(xmlReq.toXmlString());
            //处理响应报文
            if (bankResult[0].length() == 0) {
                StringBuilder tmpSb = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(bankResult[1], tmpSb);
                if (tmpBkReader != null) {
                    String acceptFlag=tmpBkReader.getFirstText("/h2h/respInfo/acceptFlag");//报文受理状态
                    String respCode = tmpBkReader.getFirstText("/h2h/respInfo/respCode");//返回结果码
                    String respInfo = tmpBkReader.getFirstText("/h2h/respInfo/respMsg");//返回结果说明
                    if("1".equals(acceptFlag)){//受理成功
                        if ("1".equals(tmpBkReader.getFirstText("/h2h/resp/statusFlag"))) {//查询处理状态 1有 -1无
                            detail.respCode = "0";
                            detail.respInfo = respInfo;
                            detail.actNum = p_req7506.readedDetail.actNum;//账号
                            while (tmpBkReader.read("/h2h/resp/row")){
                                detail.actCur = convertCurToATS(tmpBkReader.readedXElement.getSingleTextNotNull("currCode"));//币种
                                detail.availBal = tmpBkReader.readedXElement.getSingleTextNotNull("availablBalance");//可用余额
                                detail.currBal = tmpBkReader.readedXElement.getSingleTextNotNull("balance");//当前余额
                            }
                        }else {
                            Date blsDate=new Date();
                            int num=1;
                            //如当天余额没有变化，则会返回-1，需要往前一天查询，至多查询前10天
                            while (num<=10 && StringHelper.isNullOrEmpty(detail.respCode)){
                                num++;
                                Calendar calendar=Calendar.getInstance();
                                calendar.setTime(blsDate);
                                calendar.add(Calendar.DAY_OF_MONTH, -1);
                                blsDate = calendar.getTime();
                                String resp=getBanlce(p_req7506.readedDetail.actNum,Format.Date10Format.format(blsDate));
                                if(StringHelper.hasAnyChar(resp)){
                                    StringBuilder tmpSb2 = new StringBuilder();
                                    XmlTextReader tmpBkReader2 = loadBankRespXmlReader(resp, tmpSb2);
                                    detail.respCode = "0";
                                    detail.respInfo = tmpBkReader2.getFirstText("/h2h/respInfo/respMsg");//返回结果说明
                                    detail.actNum = p_req7506.readedDetail.actNum;//账号
                                    while (tmpBkReader2.read("/h2h/resp/row")){
                                        detail.actCur = convertCurToATS(tmpBkReader2.readedXElement.getSingleTextNotNull("currCode"));//币种
                                        detail.availBal = tmpBkReader2.readedXElement.getSingleTextNotNull("availablBalance");//可用余额
                                        detail.currBal = tmpBkReader2.readedXElement.getSingleTextNotNull("balance");//当前余额
                                    }
                                }
                            }
                            if(StringHelper.isNullOrEmpty(detail.respCode)){
                                detail.respCode = "0";
                                detail.respInfo = "未查询到余额";
                            }
                        }
                    }else {//受理未响应或受理失败
                        detail.respCode="-1";
                        detail.respInfo=respCode+"："+respInfo;
                    }
                }else{
                    detail.respCode = "-1";
                    detail.respInfo = tmpSb.toString();
                }
            }else{
                detail.respCode = "-1";
                detail.respInfo = bankResult[1];
            }
            retAts.writeRetDetail(detail, p_req7506.isBatch);
        }
        retAts.writeEnd();
        return retAts;
    }

    @Override
    public RetAts7505HisBalQry d_7505_BalQry(Req7505HisBalQry p_req7505) throws Exception {
        return "1".equals(getBankConfig().getValueAsString("channelFlag"))?d_7505_BalQry_Xml(p_req7505):d_7505_BalQry_MT(p_req7505);
    }

    /**
     * MT文件方式--历史余额查询
     * @param p_req7505
     * @return
     * @throws Exception
     */
    public RetAts7505HisBalQry d_7505_BalQry_MT(Req7505HisBalQry p_req7505) throws Exception {
        //查询时间校验
        String[] dateAry=getQueryDate(p_req7505.dateFrom,p_req7505.dateTo);
        p_req7505.dateFrom=dateAry[0];
        p_req7505.dateTo=dateAry[1];

        RetAts7505HisBalQry retAts = new RetAts7505HisBalQry(p_req7505.reqHeader);
        String tmpRespCode = "";
        String tmpRespInfo = "";
        retAts.writeStart();//写返回ATS的统一头部信息
        try{
            String accNum = p_req7505.actNum;
            Date dateStart = Format.Date8Format.parse(p_req7505.dateFrom);
            Date dateEnd = Format.Date8Format.parse(p_req7505.dateTo);
            Calendar calendar=Calendar.getInstance();
            while (!dateStart.after(dateEnd)){
                String dealedPath = getBankConfig().getValueAsString("DealedPath")+File.separator+
                        Format.Date8Format.format(dateStart)+File.separator+"MT940"+File.separator+
                        accNum+"_7505.txt";
                if(!FileHelper.existFile(dealedPath)){
                    calendar.setTime(dateStart);
                    calendar.add(Calendar.DAY_OF_MONTH, 1);
                    dateStart = calendar.getTime();
                    continue;
                }
                //读取文件内容
                String balanceContent = FileHelper.readFileText(dealedPath,getCharset());
                WriteBankLogLn("读取到的文件内容："+balanceContent);
                if(StringHelper.hasAnyChar(balanceContent)){
                    //账号|币种|当前余额|可用余额|昨日余额(MT940)|页码
                    String[] bal  =balanceContent.split("\\|");
                    RetAtsHisBalDetail tmpRetDetail = new RetAtsHisBalDetail();
                    tmpRetDetail.actBal=bal[2].trim();
                    tmpRetDetail.availBal=bal[3].trim();
                    tmpRetDetail.balDate=Format.Date10Format.format(dateStart);
                    retAts.writeRetDetail(tmpRetDetail);
                }else {
                    tmpRespCode="-1";
                    tmpRespInfo="文件读取异常";
                }
                calendar.setTime(dateStart);
                calendar.add(Calendar.DAY_OF_MONTH, 1);
                dateStart = calendar.getTime();
            }
        } catch (Exception e) {
            tmpRespCode = "-1";
            tmpRespInfo = e.getMessage();
            e.printStackTrace();
        }
        if (tmpRespCode.equals("-1")) {
            retAts = new RetAts7505HisBalQry(p_req7505.reqHeader);
            retAts.writeStart();//写返回ATS的统一头部信息
            retAts.writeRespCode(tmpRespCode);
            retAts.writeRespInfo(tmpRespInfo);
        } else if (retAts.getWrittenRdCount() == 0) {
            retAts.writeRespCode("0");
            retAts.writeRespInfo("返回结果为空，所查询时间段内不存在历史余额");
        }
        retAts.writeEnd();
        return retAts;
    }

    /**
     * 请求报文方式--历史余额查询
     * @param p_req7505
     * @return
     * @throws Exception
     */
    public RetAts7505HisBalQry d_7505_BalQry_Xml(Req7505HisBalQry p_req7505) throws Exception {
        RetAts7505HisBalQry retAts = new RetAts7505HisBalQry(p_req7505.reqHeader);
        String tmpRespCode = "";
        String tmpRespInfo = "";
        retAts.writeStart();//写返回ATS的统一头部信息
        //拼接请求报文体
        MUFG01Header header=new MUFG01Header();
        header.transCode="h2h.001.001";
        header.pkgNo = getQryTransID();
        XmlTextWriter xmlReq = new XmlTextWriter();
        writeReqHeader(xmlReq,header);
        xmlReq.writeStartElement("req");
        xmlReq.writeElementString("accNo",p_req7505.actNum);//帐号
        xmlReq.writeElementString("beginDate",DateHelper.convertD8toD10(p_req7505.dateFrom));//查询开始日期
        xmlReq.writeElementString("endDate",DateHelper.convertD8toD10(p_req7505.dateTo));//查询结束日期
        xmlReq.writeEndDocument();
        //请求银行并获取响应结果
        String[] bankResult = sendToBank(xmlReq.toXmlString());
        //处理响应报文
        if (bankResult[0].length() == 0) {
            StringBuilder tmpSb = new StringBuilder();
            XmlTextReader tmpBkReader = loadBankRespXmlReader(bankResult[1], tmpSb);
            if (tmpBkReader != null) {
                String acceptFlag=tmpBkReader.getFirstText("/h2h/respInfo/acceptFlag");//报文受理状态
                String respCode = tmpBkReader.getFirstText("/h2h/respInfo/respCode");//返回结果码
                String respInfo = tmpBkReader.getFirstText("/h2h/respInfo/respMsg");//返回结果说明
                if("1".equals(acceptFlag)){//受理成功
                    if ("1".equals(tmpBkReader.getFirstText("/h2h/resp/statusFlag"))) {//查询处理状态 1有 -1无
                        retAts.writeRespCode("0");
                        retAts.writeRespInfo(respInfo);
                        while (tmpBkReader.read("/h2h/resp/row")){
                            RetAtsHisBalDetail tmpRetDetail = new RetAtsHisBalDetail();
                            tmpRetDetail.balDate = tmpBkReader.readedXElement.getSingleTextNotNull("balanceDate");//日期
                            tmpRetDetail.availBal = tmpBkReader.readedXElement.getSingleTextNotNull("availablBalance");//可用余额
                            tmpRetDetail.actBal = tmpBkReader.readedXElement.getSingleTextNotNull("balance");//当前余额
                            retAts.writeRetDetail(tmpRetDetail);
                        }
                    }else {//查询失败或无数据 测试时需注意下无数据的情况是返回什么
                        tmpRespCode="0";
                        tmpRespInfo="根据查询条件没有得到对象记录";
                    }
                }else {//受理未响应或受理失败
                    tmpRespCode="-1";
                    tmpRespInfo=respCode+"："+respInfo;
                }
            }else {
                tmpRespCode="-1";
                tmpRespInfo=tmpSb.toString();
            }
        }else {
            tmpRespCode="-1";
            tmpRespInfo=bankResult[1];
        }
        if ("-1".equals(tmpRespCode)) {
            retAts = new RetAts7505HisBalQry(p_req7505.reqHeader);
            retAts.writeStart();//写返回ATS的统一头部信息
            retAts.writeRespCode(tmpRespCode);
            retAts.writeRespInfo(tmpRespInfo);
        } else if (retAts.getWrittenRdCount() == 0) {
            retAts.writeRespCode("0");
            retAts.writeRespInfo("返回结果为空，所查询时间段内不存在历史余额");
        }
        retAts.writeEnd();
        return retAts;
    }
}
